package com.xinyue.gateway.server.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import com.xinyue.gateway.server.message.GateMessageHeader;
import com.xinyue.gateway.server.message.GateMessagePackage;
import com.xinyue.network.message.InnerMessageCodecFactory;
import com.xinyue.utils.Crc32Util;
import com.xinyue.utils.DateUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;

/**
 * 这里处理收到业务服务发送来的消息，加工成返回客户端的包。<br>
 * 返回给客户端的协议格式：total(4) + seqId(4) + uniqueMessageId(4) + errorCode(4) + body(protobuf字节数组)
 * 
 * @author 心悦网络科技有限公司 王广帅
 *
 * @Date 2018年6月14日 下午2:25:20
 */
@Service
@Scope(scopeName = "prototype")
public class GameMessageEncodeHandler extends ChannelOutboundHandlerAdapter {
    private static Logger logger = LoggerFactory.getLogger(GameMessageEncodeHandler.class);
    InnerMessageCodecFactory codecFactory = InnerMessageCodecFactory.getInstance();
    // 固定的消息头长度
    private final static int Head_Length = 31;
    
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        //编码，向客户端返回消息
    	GateMessagePackage gateLocalMessage = (GateMessagePackage) msg;
        int initialCapacity = Head_Length;
        byte[] body = gateLocalMessage.getBody();
        int bodyLength = 0;
        if (body != null) {
            bodyLength = body.length;
        }
        int maxCapacity = initialCapacity + bodyLength;
        if (maxCapacity >= Short.MAX_VALUE) {
            logger.error("返回的消息太多,大于{}",Short.MAX_VALUE);
            return;
        }
        GateMessageHeader messageHeader = gateLocalMessage.getHeader();
        ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(initialCapacity);
        byteBuf.writeShort(maxCapacity);
        byteBuf.writeInt(messageHeader.getSeqId());
        byteBuf.writeInt(messageHeader.getMessageId());
        byteBuf.writeLong(DateUtil.getServerTime());
        //根据消息长度判断是否要压缩
        byte zipFlag = getZipFlag(bodyLength);
        byteBuf.writeByte(zipFlag);
        //服务器可能返回给客户端错误码
        byteBuf.writeInt(messageHeader.getErrorCode());
        if (messageHeader.getErrorCode() == 0 && body != null) {
            if(zipFlag == 1) {
                body = zipBody(body);
            }
            long crcValue = Crc32Util.crc32(body);
            byteBuf.writeLong(crcValue);
            byteBuf.writeBytes(body);
        }
        ctx.writeAndFlush(byteBuf);
    }
    private byte[] zipBody(byte[] body) {
        return body;
    }

    private byte getZipFlag(int bodyLength) {
        if (bodyLength > 4096) {
            return (byte) 1;
        }
        return (byte) 0;
    }
}
